//  Inside Microsoft Exchange 2007 Web Services
//  Chapter 5
//
//  Copyright (c) 2007 David Sterling, Ben Spain, Mark Taylor, Huw Upshall, Michael Mainer.
//  All rights reserved.
//
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Xml;
using System.IO;
using ProxyHelpers.EWS;

namespace GetItemAndAllHeaders
{
    class Program
    {
        static void Main(string[] args)
        {
            ExchangeServiceBinding binding = new ExchangeServiceBinding();
            binding.Url = @"https://yourServer/ews/Exchange.asmx";
            binding.Credentials = new NetworkCredential(
                "username",
                "password",
                "domain");

            // You need to use a message that has been received here.  A
            // draft will not have any headers yet.  Of course, the below
            // will not work for you until you replace the id with a valid
            // one from your mailbox.
            //
            ItemType[] foundItems = EWSHelpers.FindAllItemsInFolder(
                                binding,
                                new DistinguishedFolderIdType(
                                    DistinguishedFolderIdNameType.inbox),
                                new ItemResponseShapeType(
                                    DefaultShapeNamesType.Default));

            if (foundItems != null)
            {
                foreach (ItemType item in foundItems)
                {
                    ItemType itemWithHeaders = GetItemAndAllHeaders(binding, item.ItemId);
                    Console.WriteLine("====== Message: " + itemWithHeaders.Subject);
                    foreach (InternetHeaderType header in itemWithHeaders.InternetMessageHeaders)
                    {
                        Console.WriteLine("Header: {0}, Value: {1}",
                            header.HeaderName,
                            header.Value);
                    }
                }
            }
        }

        /// <summary>
        /// Returns an item along with all of its internet message header values (Listing 5-49)
        /// </summary>
        /// <param name="binding">Binding to use for calls</param>
        /// <param name="id">Id of item to get</param>
        /// <returns>ItemType instance</returns>
        /// 
        public static ItemType GetItemAndAllHeaders(
                            ExchangeServiceBinding binding,
                            ItemIdType id)
        {
            // First, we need to get all the header names and then build up another 
            // request to fetch each header explicitly.
            //
            GetItemType firstGetRequest = new GetItemType();
            firstGetRequest.ItemShape = new ItemResponseShapeType(
                       DefaultShapeNamesType.IdOnly,
                       new PathToUnindexedFieldType(
                               UnindexedFieldURIType.itemInternetMessageHeaders));

            firstGetRequest.ItemIds = new ItemIdType[] { id };

            GetItemResponseType firstGetResponse = binding.GetItem(firstGetRequest);
            ItemInfoResponseMessageType firstMessage =
                        firstGetResponse.ResponseMessages.Items[0] as
                               ItemInfoResponseMessageType;
            if (firstMessage.ResponseCode != ResponseCodeType.NoError)
            {
                throw new Exception("First get failed with error code: " +
                            firstMessage.ResponseCode.ToString());
            }

            // Now, we need to cycle through all the headers to get the names so we 
            // can make our second request for the header values.
            //
            ItemType item = firstMessage.Items.Items[0];
            BasePathToElementType[] additionalProps = null;
            if (item.InternetMessageHeaders != null)
            {
                additionalProps = new
                         BasePathToElementType[item.InternetMessageHeaders.Length];
                int index = 0;
                foreach (InternetHeaderType headerName in item.InternetMessageHeaders)
                {
                    PathToIndexedFieldType headerPath = new PathToIndexedFieldType(
                          DictionaryURIType.itemInternetMessageHeader,
                          headerName.HeaderName);

                    additionalProps[index++] = headerPath;
                }
            }

            // Now that we have the additional props set up, make our second 
            // request.
            //
            GetItemType secondGetRequest = new GetItemType();
            secondGetRequest.ItemShape = new ItemResponseShapeType(
                            DefaultShapeNamesType.IdOnly,
                            additionalProps);

            secondGetRequest.ItemIds = new ItemIdType[] { id };
            GetItemResponseType secondGetResponse =
                      binding.GetItem(secondGetRequest);
            ItemInfoResponseMessageType secondMessage =
                     secondGetResponse.ResponseMessages.Items[0] as
                            ItemInfoResponseMessageType;
            if (secondMessage.ResponseCode != ResponseCodeType.NoError)
            {
                throw new Exception("Second get failed with error code: " +
                        secondMessage.ResponseCode.ToString());
            }

            return secondMessage.Items.Items[0];
        }

    }
}
